<?php
////////////////////////
// Player class script //
////////////////////////
// TODO: 
// work with constractor// Fixed
// and MakeView()
#######HEADER###########
include_once('User.php');

interface iPlayer
{
    // constractor, fetching local variables:
    /*
     * map_size_x
     * map_size_y
     * grname
     * map_mane
     * x/y_coordinate
     * direction
     * movement points
     * moving_map (left/rigth/etc..)
     * Diffenrent info about location cells
     */
    public function Player();   
    // Getting and Setting different information into cells's array:
    /*
     * x/y coordinate
     * solid
     * background
     * npc
     */
    // Information from DB
    public function GetInfo();
    //merging cell's data
    public function CreateOutput();
    // Putting the group on the output
    public function PutPlayer();
    
    public function PutOthers();
    
    // Weight of each cell starting from target ($x, $y), using map's array ($field)
    public function PutWeight($x, $y);
  
    public function PutWay($x, $y, $poids);  
    
    public function GetOutput();
    

    /***Moving fonctions***/    
    // Moving around
    public function Move($dir, $pas);
    // putting the result into the db
    public function Save();
    
    // GETS
    public function GetPlayerScreenX();
    public function GetPlayerScreenY();
    public function GetPlayerWeight();
    public function GetBuf();
}



class Player extends User implements iPlayer
{
    private $name;  // name of the group
    private $map;  // name of the group
    private $xcoor;  // main coord
    private $ycoor;
    private $xcoor_screen;  // player's coordinates on screen
    private $ycoor_screen;
    private $sprite;  // group sprite (picture)
    private $direct;  // direction
    private $mov;  // movement points
    private $view_width; // visibility in brouser
    private $view_height;
    
    private $map_output; // map buffer

    
    //map's vars
    private $mapx;
    private $mapy;

    // Movement table
    /*
    0 = right
    1 = right-up
    2 = up
    ...
    6 = down
    7 = down-right
    */
    private $mov_buf = array( 0 => array( 'x' => 1, 'y' => 0),
                              1 => array( 'x' => 1, 'y' => -1),
                              2 => array( 'x' => 0, 'y' => -1),
                              3 => array( 'x' => -1, 'y' => -1),
                              4 => array( 'x' => -1, 'y' => 0),
                              5 => array( 'x' => -1, 'y' => 1),
                              6 => array( 'x' => 0, 'y' => 1),
                              7 => array( 'x' => 1, 'y' => 1));

    // Information about visible cells
    private $cells = array();
    
    // Weight buffer for pathfinding
    private $buf_weight = array();
    
    // Personal, cell's htm


########END OF HEADER###

    //  CONSTRUCT
    public function Player()
    {
        global $db; // db initialisation
        
        $this->User();
        
        
        /*
         * Next query is getting:
         * player.grname
         * player.mapname
         * player.xcoor
         * player.ycoor
         * player.grname
         * player.direction
         * player.mov
         * maps.xmax
         * maps.ymax
         */
        $player = $db->GetLine('player, users, maps',
                              '(player.id = users.chosen_shadow) && (users.login = \''.$this->GetLogin().'\') && (maps.name = player.mapname)',
                              'player.name, player.mapname, player.xcoor, player.ycoor, player.direction, player.mov, maps.xmax, maps.ymax'); // query ^^

        // Fetching group_info varibles in local storage
        $this->name = $player['name']; 
        $this->map = $player['mapname'];
        $this->xcoor = $player['xcoor'];
        $this->ycoor = $player['ycoor'];
        $this->direct = $player['direction'];
        $this->mov = $player['mov']; // how far can the group go in one time

        // map_info varibles
        $this->xmax = $player['xmax'];
        $this->ymax = $player['ymax'];
        
        $this->view_width = ($this->GetXMap()*2)+1;
        $this->view_height = ($this->GetYMap()*2)+1;
        
        //var_export($this->cells);

        $this->GetInfo();
    }
    
    public function GetInfo()
    {
        global $db;
        
         //  Camera's coords
        if ($this->xcoor <= $this->GetXMap())
            $this->mapx = ($this->GetXMap() + 1);
        else
            $this->mapx = ($this->xcoor >= ($this->xmax - $this->GetXMap())) ? ($this->xmax - $this->GetXMap() - 1) : ($this->xcoor);
        if ($this->ycoor <= $this->GetYMap())
            $this->mapy = ($this->GetYMap() + 1);
        else
            $this->mapy = ($this->ycoor >= ($this->xmax - $this->GetYMap())) ? ($this->ymax - $this->GetYMap() - 1) : ($this->ycoor);
        
        
        // Getting player's coordinates on screen
        $this->xcoor_screen = ($this->GetXMap() + 1) + $this->xcoor - $this->mapx - 1;
        $this->ycoor_screen = ($this->GetYMap() + 1) + $this->ycoor - $this->mapy - 1;

        
        $db->Query('SELECT cells.id, cells.x, cells.y, cells.type, cells.pic, cells.solide, cells.npc FROM cells WHERE (x >= '.($this->mapx-$this->GetXMap()).') && (y >= '.($this->mapy-$this->GetYMap()).')
                                            && (x <= '.($this->mapx+$this->GetXMap()).') && (y <= '.($this->mapy+$this->GetYMap()).')
                                            && (mapname = \''.($this->map).'\')');

        $cells_info = $db->Query2Array();

        // transforming the result in normal array
        foreach ($cells_info as $id=>$data)
        {
            $this->cells[$cells_info[$id]['x']][$cells_info[$id]['y']]['solide'] = $cells_info[$id]['solide'];
            $this->cells[$cells_info[$id]['x']][$cells_info[$id]['y']]['type'] = $cells_info[$id]['type']; 
            $this->cells[$cells_info[$id]['x']][$cells_info[$id]['y']]['back'] = $cells_info[$id]['pic']; 
            $this->cells[$cells_info[$id]['x']][$cells_info[$id]['y']]['npc'] = $cells_info[$id]['npc']; 
            
        }
    }

    public function CreateOutput()
    {
        // The result of mindbreak -_-   ..................................... <===
        // I DON'T KNOW HOW IT WORKS!
        global $db;
        
        $map_output = '';
        // world of headache (don't ask how it works...  -_-)
        // draw the local terrain
        for ($ycell = ($this->mapy-$this->GetYMap()); $ycell <= $this->mapy+$this->GetYMap(); $ycell++)
        {
            for ($xcell = ($this->mapx-$this->GetXMap()); $xcell <= $this->mapx+$this->GetXMap(); $xcell++)
            {
                $map_output .=  ($xcell == ($this->mapx+($this->GetXMap()))) ? '<div class="cell" style="background-image: url(templates/data/map/'.$this->cells[$xcell][$ycell]['back'].'.png)" onclick="javascript: sendPOSTreqMap(\'x='.($xcell - ($this->mapx-$this->GetXMap())).'&y='.($ycell - ($this->mapy-$this->GetYMap())).'\', \'map.php\', \'map_output\', getcom);" name="'.$xcell.'_'.$ycell.'"></div><div class="sep"></div>'."\n" : '<div class="cell" style="background-image: url(templates/data/map/'.$this->cells[$xcell][$ycell]['back'].'.png)" onclick="javascript: sendPOSTreqMap(\'x='.($xcell - ($this->mapx-$this->GetXMap())).'&y='.($ycell - ($this->mapy-$this->GetYMap())).'\', \'map.php\', \'map_output\', getcom);" name="'.$xcell.'_'.$ycell.'"></div>'."\n";
            }
        }

        $this->map_output = $map_output; // putting the result into local varib

        return $map_output;

    }

    public function PutPlayer()
    {
        /*for ($i=1; $i<=$this->mov; $i++)
        {
            for ($k=0; $k<=7; $k++)
            {
                if (in_array($k, array(0, 2, 4, 6)))
                    $this->map_output = str_replace('name="'.($this->xcoor+($this->mov_buf[$k]['x']*$i)).'_'.($this->ycoor+($this->mov_buf[$k]['y']*$i)).'"></div>', 'name="'.($this->xcoor+($this->mov_buf[$k]['x']*$i)).'_'.($this->ycoor+($this->mov_buf[$k]['y']*$i)).'" onclick="javascript: sendPOSTreqMap(\'dir='.$k.'&pas='.$i.'\', \'map.php\', \'map_output\', getcom);">1</div>', $this->map_output);
                else
                    $this->map_output = str_replace('name="'.($this->xcoor+($this->mov_buf[$k]['x'])).'_'.($this->ycoor+($this->mov_buf[$k]['y'])).'"></div>', 'name="'.($this->xcoor+($this->mov_buf[$k]['x'])).'_'.($this->ycoor+($this->mov_buf[$k]['y'])).'" onclick="javascript: sendPOSTreqMap(\'dir='.$k.'&pas='.$i.'\', \'map.php\', \'map_output\', getcom);">1</div>', $this->map_output);
            }
        }*/
        // TODO: CHANGE players folder
        // Main perso image
        $this->map_output = str_replace('name="'.$this->xcoor.'_'.$this->ycoor.'"></div>', 'name="'.$this->xcoor.'_'.$this->ycoor.'"><img src="templates/data/player/def/'.$this->direct.'.png" width="32" height="32"></div>', $this->map_output);
    }
    
    public function PutOthers()
    {
        global $db;
        
        
        $db->Query('SELECT player.id, player.xcoor, player.ycoor, player.direction FROM users, player WHERE
                   (users.chosen_shadow = player.id) && 
                   (users.authtime > '.(time()-1800).') && 
                   (not users.login = \''.$this->GetLogin().'\') && 
                   (player.xcoor >= '.($this->mapx-$this->GetXMap()).') && 
                   (player.ycoor >= '.($this->mapy-$this->GetYMap()).') && 
                   (player.xcoor <= '.($this->mapx+$this->GetXMap()).') && 
                   (player.ycoor <= '.($this->mapy+$this->GetYMap()).') &&
                   (player.mapname = \''.($this->map).'\')');
        
        $others = $db->Query2Array();
        if (!empty($others))
            foreach ($others as $id=>$data)
                $this->map_output = str_replace('name="'.$others[$id]['xcoor'].'_'.$others[$id]['ycoor'].'"></div>', 'name="'.$others[$id]['xcoor'].'_'.$others[$id]['ycoor'].'"><img src="templates/data/player/def/'.$others[$id]['direction'].'.png" width="32" height="32"></div>', $this->map_output);
    }
    
    
    public function PutWeight($x, $y)
    {
        
        $this->buf_weight = array_fill(0, $this->view_width, array_fill(0, $this->view_height, 0)); 
        if ($this->cells[$this->mapx - $this->GetXMap() + $x][$this->mapy - $this->GetYMap() + $y]['solide'])
        {   
        if (($x > $this->view_width) || ($y > $this->view_height))
            die('Wrong parametr in PutWeight');
        $this->buf_weight[$x][$y] = 1; // target cell has weight = 1
        // Isn't this cycle awsome? : )
        for ($poids = 1; $poids <= 100; $poids++)
        {  // weight increasement (will be broken by break4)
            for ($y1 = 0; $y1<=($this->view_height - 1); $y1++) // y coor of buffer
                for ($x1 = 0; $x1<=($this->view_width - 1); $x1++)
                    if ($this->buf_weight[$x1][$y1] == $poids) // starting building new weight
                        for ($i = -2; $i++, $i <= 1; $i++)  // $i is in (-1, 1)
                        {
                            if (isset($this->buf_weight[$x1+$i][$y1]))
                                if ($this->cells[$this->mapx - $this->GetXMap() + $x1 + $i][$this->mapy - $this->GetYMap() + $y1]['solide'])
                                    if ($this->buf_weight[$x1+$i][$y1] == 0)
                                    {
                                        $this->buf_weight[$x1+$i][$y1] = $poids+1;
                                        if ((($x1+$i) == $this->xcoor_screen) && (($y1) == $this->ycoor_screen))
                                            break 4;
                                    }
                                    
                            if (isset($this->buf_weight[$x1][$y1+$i]))
                                if ($this->cells[$this->mapx - $this->GetXMap() + $x1][$this->mapy - $this->GetYMap() + $y1 + $i]['solide'])
                                    if ($this->buf_weight[$x1][$y1+$i] == 0)
                                    {
                                        $this->buf_weight[$x1][$y1+$i] = $poids+1;
                                        if ((($x1) == $this->xcoor_screen) && (($y1+$i) == $this->ycoor_screen))
                                            break 4;
                                    }  
                        }
            }
        }
    }

    public function PutWay($x, $y, $poids)
    {
        //var_dump($x);
        $x = intval($x);
        $y = intval($y);
        if ($poids == 0)
            return; 
        else
        { 
            for ($i = -2; $i++, $i <= 1; $i++)
            { 
                if (isset($this->buf_weight[$x+$i][$y]))
                    if (($this->buf_weight[$x+$i][$y]) == $poids)
                    {
                        $this->map_output = str_replace('name="'.($this->mapx - $this->GetXMap() + $x + $i).'_'.($this->mapy - $this->GetYMap() + $y).'"></div>', 'name="'.($this->mapx - $this->GetXMap() + $x + $i).'_'.($this->mapy - $this->GetYMap() + $y).'">0</div>', $this->map_output);
                        $this->PutWay(($x+$i), $y, ($poids - 1));
                        break;
                    }
                 
                if (isset($this->buf_weight[$x][$y+$i]))
                    if ($this->buf_weight[$x][$y+$i] == $poids)
                    {
                        $this->map_output = str_replace('name="'.($this->mapx - $this->GetXMap() + $x).'_'.($this->mapy - $this->GetYMap() + $y + $i).'"></div>', 'name="'.($this->mapx - $this->GetXMap() + $x).'_'.($this->mapy - $this->GetYMap() + $y + $i).'">0</div>', $this->map_output); 
                        $this->PutWay($x, ($y+$i), ($poids - 1)); 
                        break;
                    }
            }
        }
    
    }

    public function GetOutput()
    {
        return $this->map_output;
    }
    
    
    
    
    public function Move($dir, $pas)
    {
        global $db;

        // Security check
        if ($pas > $this->mov)
            die('wrong param in Mov(dir, pas)');

        // security check
        if (in_array($dir, array(0,1, 2,3, 4,5, 6,7)))
            $this->direct = $dir;
        //else

        for ($p=1; $p<=$pas; $p++)
        {
        // First check: if there is no obstacles OR if a cell even exist...
            if ($this->cells[($this->xcoor+$this->mov_buf[$dir]['x'])][($this->ycoor+$this->mov_buf[$dir]['y'])]['solide'])
            {
                $this->xcoor = $this->xcoor + $this->mov_buf[$dir]['x'];
                $this->ycoor = $this->ycoor + $this->mov_buf[$dir]['y'];
            }
        }
        
        $this->GetInfo();
    }

    public function Save()
    {
        global $db;

        $db->UpdateData('player, users', array('player.xcoor' => $this->xcoor,
                                               'player.ycoor' => $this->ycoor,
                                               'player.direction' => $this->direct), '(player.id = users.chosen_shadow) && (users.login = \''.$this->GetLogin().'\')');
    }
    
    // Gets go here...
    public function GetPlayerScreenX()
    {
        return $this->xcoor_screen;
    }
    
    public function GetPlayerScreenY()
    {
        return $this->ycoor_screen;
    }
    
    public function GetPlayerWeight()
    {
        return $this->buf_weight[$this->xcoor_screen][$this->ycoor_screen];
    }
    
    public function GetBuf()
    {
        return $this->buf_weight;
    }


}


?>
